

/*********************************************************/
#define bool_t     unsigned char

#define uint8_t     unsigned char
#define uint16_t    unsigned short int
#define uint32_t    unsigned long int
#define uint64_t    unsigned long long

#define int8_t     char
#define int16_t    short int
#define int32_t    long int
#define int64_t    long long


/*********************************************************/
void print_init(void)
{
}

void print_char(uint8_t ch)
{
	printf("%02X ", ch);
}

/*********************************************************/
//test how many parames the function can take
void test_how_many_params_0(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g, uint8_t h, uint8_t i, uint8_t j, uint8_t k, uint8_t l,uint8_t m)
{
	print_char(a);
	print_char(b);
	print_char(c);
	print_char(d);
	print_char(e);
	print_char(f);
	print_char(g);
	print_char(h);
	print_char(i);
	print_char(j);
	print_char(k);
	print_char(l);
	print_char(m);
}

void test_how_many_params_1(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g, uint8_t h, uint8_t i, uint8_t j, uint8_t k, uint8_t l,uint8_t m)
{
	test_how_many_params_0(0xfa, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
	print_char(a);
	print_char(b);
	print_char(c);
	print_char(d);
	print_char(e);
	print_char(f);
	print_char(g);
	print_char(h);
	print_char(i);
	print_char(j);
	print_char(k);
	print_char(l);
	print_char(m);
}

void test_how_many_params_2(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g, uint8_t h, uint8_t i, uint8_t j, uint8_t k, uint8_t l,uint8_t m)
{
	test_how_many_params_1(0xfb,1,2,3,4,5,6,7, 8 ,9, 10, 11, 12);
	print_char(a);
	print_char(b);
	print_char(c);
	print_char(d);
	print_char(e);
	print_char(f);
	print_char(g);
	print_char(h);
	print_char(i);
	print_char(j);
	print_char(k);
	print_char(l);
	print_char(m);
}

void test_how_many_params(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g, uint8_t h, uint8_t i, uint8_t j, uint8_t k, uint8_t l,uint8_t m)
{
	test_how_many_params_2(0xfc, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
	print_char(a);
	print_char(b);
	print_char(c);
	print_char(d);
	print_char(e);
	print_char(f);
	print_char(g);
	print_char(h);
	print_char(i);
	print_char(j);
	print_char(k);
	print_char(l);
	print_char(m);
}

/*********************************************************/
//test if the local param will push to the stack when call a sub function
void test_if_push_local_param_to_stack(uint8_t a)
{
	uint8_t b;
	print_char(0x0a);
	print_char(a);
	if(a > 0){
		b = a - 1;
		test_if_push_local_param_to_stack(b);
	}
	else{
        b = 0;
	}
	print_char(b);
	print_char(0x0b);
}

/*********************************************************/
//test if can using the pionter to get data
void test_using_data_pionter(void)
{
	uint8_t *p;
	uint8_t x;
	uint8_t y;

	x = 0xab;
	p = &x;
	y = *p;

	print_char(y);
}

/*********************************************************/
//test if can using the pionter to call function
void test_using_fun_pionter_0(void)
{
	print_char(0xcd);
}

void (*test_using_fun_pionter_fun)(void);
void test_using_fun_pionter(void)
{
	test_using_fun_pionter_fun = test_using_fun_pionter_0;
	test_using_fun_pionter_fun();
}

/*********************************************************/
//test if the function pionter can take param
void (*test_fun_pionter_take_param_fun)(uint8_t n);
void test_fun_pionter_take_param(void)
{
	uint8_t a;
	a = 0xef;
	test_fun_pionter_take_param_fun = print_char;
	test_fun_pionter_take_param_fun(a);
}

/*********************************************************/
//test if the function can return param
uint8_t test_retur_param_0(void)
{
	uint8_t x;
	x = 0x1a;
	return x;
}

void test_retur_param(void)
{
	print_char(test_retur_param_0());
}

/*********************************************************/
//test if the function can return pointer
uint8_t test_retur_pointer_param;
uint8_t* test_retur_pointer_0(void)
{
	return &test_retur_pointer_param;
}

void test_retur_pointer(void)
{
	uint8_t *p;
	test_retur_pointer_param = 0x1b;
	p = test_retur_pointer_0();
	print_char(*p);
}

/*********************************************************/
//test array
uint8_t test_array_buff[8] = {0,1,2,3,4,5,6,7};
uint16_t test_array_buff_16[8] = {0xe0c0, 0xe1c1, 0xe2c2, 0xe3c3, 0xe4c4, 0xe5c5, 0xe6c6, 0xe7c7};
void test_array_0(uint8_t* buff, uint8_t len)
{
	while(len != 0){
		print_char(buff[len-1]);
		len--;
	}
}

void test_array_1(uint8_t* buff, uint8_t len)
{
	while(len != 0){
		print_char(*buff);
		buff++;
		len--;
	}
}

void test_array_2(uint16_t* buff, uint8_t len)
{
	uint16_t t16;
	uint8_t t8;
	while(len != 0){
		t16 = buff[len-1];
		t8 = t16>>8;
		print_char(t8);
		t8 = (uint8_t)t16;
		print_char(t8);
		len--;
	}
}

void test_array_3(uint16_t* buff, uint8_t len)
{
	uint16_t t16;
	uint8_t t8;
	while(len != 0){
		t16 = *buff;
		t8 = t16>>8;
		print_char(t8);
		t8 = (uint8_t)t16;
		print_char(t8);
		buff++;
		len--;
	}
}

void test_array(void)
{
	test_array_0(test_array_buff, 8);
	test_array_1(test_array_buff, 8);
	test_array_2(test_array_buff_16, 8);
	test_array_3(test_array_buff_16, 8);
}

/*********************************************************/
//test array_2d
uint8_t test_array_2d_buff[8][2] = {
								{00,10},
								{01,11},
								{02,12},
								{03,13},
								{04,14},
								{05,15},
								{06,16},
								{07,17},
									};
uint16_t test_array_2d_buff_16[8][2] = {
								{0x2d00,0x2d10},
								{0x2d01,0x2d11},
								{0x2d02,0x2d12},
								{0x2d03,0x2d13},
								{0x2d04,0x2d14},
								{0x2d05,0x2d15},
								{0x2d06,0x2d16},
								{0x2d07,0x2d17},
										};
void test_array_2d_0(uint8_t buff[][2], uint8_t l)
{
	uint8_t c;
	while(l != 0){
		c = 2;
		while(c != 0){
			print_char(buff[l-1][c-1]);
			c--;
		}
		l--;
	}
}

void test_array_2d_2(uint16_t buff[][2], uint8_t l)
{
	uint16_t t16;
	uint8_t t8;

	uint8_t c;
	while(l != 0){
		c = 2;
		while(c != 0){
			t16 = buff[l-1][c-1];
			t8 = t16>>8;
			print_char(t8);
			t8 = (uint8_t)t16;
			print_char(t8);
			c--;
		}
		l--;
	}
}

void test_array_2d(void)
{
	test_array_2d_0(test_array_2d_buff, 8);
	test_array_2d_2(test_array_2d_buff_16, 8);
}

/*********************************************************/
//test pointer length
void test_pointer_length(void)
{
    void *p;
    uint8_t n;
    n = sizeof(p);
    print_char(n);
}

/*********************************************************/
//test struct
typedef struct {
    uint8_t* sp;
}T_ST_0;

typedef struct {
    uint16_t s16_0;
    uint8_t s8_0;
    T_ST_0* sp;
    uint16_t s16_1;
    uint8_t s8_1;

}T_ST;
T_ST test_st[3];
T_ST_0 test_spp[3];
uint8_t test_sp[3];

T_ST* test_struct_0(void)
{
	T_ST* st_p;
	T_ST_0* spp;
	st_p = test_st;

	st_p->s16_0 = 0x0102;
	st_p->s8_0 = 0x03;
	st_p->s16_1 = 0x0405;
	st_p->s8_1 = 0x06;
	st_p->sp = &(test_spp[0]);
	spp = st_p->sp;
	spp->sp = &(test_sp[0]);

	test_st[1].s16_0 = 0x1112;
	test_st[1].s8_0 = 0x13;
	test_st[1].s16_1 = 0x1415;
	test_st[1].s8_1 = 0x16;
	test_st[1].sp = &(test_spp[1]);
	spp = test_st[1].sp;
	spp->sp = &(test_sp[1]);

	st_p++;
	st_p++;
	st_p->s16_0 = 0x2122;
	st_p->s8_0 = 0x23;
	st_p->s16_1 = 0x2425;
	st_p->s8_1 = 0x56;
	st_p->sp = &(test_spp[2]);
    spp = st_p->sp;
	spp->sp = &(test_sp[2]);

	test_sp[0] = 0xf1;
	test_sp[1] = 0xf2;
	test_sp[2] = 0xf3;

	st_p = test_st;;
	return st_p;
}

void test_struct_1(T_ST* st_p)
{
	uint16_t t16;
	uint8_t t8;
	uint8_t n;
	T_ST_0* spp;

	n = 0;
	while(n < 3){
		t16 = st_p[n].s16_0;
		t8 = t16>>8;
		print_char(t8);
		t8 = (uint8_t)t16;
		print_char(t8);

		t8 = st_p[n].s8_0;
		print_char(t8);

		t16 = st_p[n].s16_1;
		t8 = t16>>8;
		print_char(t8);
		t8 = (uint8_t)t16;
		print_char(t8);

		t8 = st_p[n].s8_1;
		print_char(t8);

        spp = st_p[n].sp;
		t8 = *(spp->sp);
		print_char(t8);
		
		n++;
	}

	n = 0;
	while(n < 3){
		t16 = st_p->s16_0;
		t8 = t16>>8;
		print_char(t8);
		t8 = (uint8_t)t16;
		print_char(t8);

		t8 = st_p->s8_0;
		print_char(t8);

		t16 = st_p->s16_1;
		t8 = t16>>8;
		print_char(t8);
		t8 = (uint8_t)t16;
		print_char(t8);

		t8 = st_p->s8_1;
		print_char(t8);

        spp = st_p->sp;
		t8 = *(spp->sp);
		print_char(t8);

		st_p++;
		n++;
	}
}

void test_struct_2(T_ST* st_p)
{
    T_ST_0* spp;
	uint8_t n;
	n = 0;
	while(n < 3){
		st_p->s16_0++;
		st_p->s8_0++;
		st_p->s16_1++;
		st_p->s8_1++;
        spp = st_p->sp;
		(*(spp->sp))++;
		st_p++;
		n++;
	}
}

void test_struct(void)
{
	T_ST* st_p;
	st_p = test_struct_0();
	test_struct_1(st_p);
	test_struct_2(st_p);
	test_struct_1(st_p);
}

/*********************************************************/
/*********************************************************/
void compiler_test(void)
{
	print_init();

	/*******************************************/
	print_char(0xaa);
	print_char(0x01);
	test_how_many_params(0,1,2,3,4,5,6,7, 8 ,9, 10, 11, 12);
	print_char(0x55);

	/*******************************************/
	print_char(0xaa);
	print_char(0x02);
	test_if_push_local_param_to_stack(5);
	print_char(0x55);

	/*******************************************/
	print_char(0xaa);
	print_char(0x03);
	test_using_data_pionter();
	print_char(0x55);

	/*******************************************/
	print_char(0xaa);
	print_char(0x04);
	test_using_fun_pionter();
	print_char(0x55);

	/*******************************************/
	print_char(0xaa);
	print_char(0x05);
	test_fun_pionter_take_param();
	print_char(0x55);

	/*******************************************/
	print_char(0xaa);
	print_char(0x06);
	test_retur_param();
	print_char(0x55);

	/*******************************************/
	print_char(0xaa);
	print_char(0x07);
	test_retur_pointer();
	print_char(0x55);

	/*******************************************/
	print_char(0xaa);
	print_char(0x08);
	test_array();
	print_char(0x55);

	/*******************************************/
	print_char(0xaa);
	print_char(0x09);
	test_array_2d();
	print_char(0x55);

	/*******************************************/
	print_char(0xaa);
	print_char(0x0a);
	test_pointer_length();
	print_char(0x55);

	/*******************************************/
	print_char(0xaa);
	print_char(0x0b);
	test_struct();
	print_char(0x55);

	while(1);
}


/******************************************
AA 01 
		FA 0B 0A 09 08 07 06 05 04 03 02 01 00 
		FB 01 02 03 04 05 06 07 08 09 0A 0B 0C 
		FC 0B 0A 09 08 07 06 05 04 03 02 01 00 
		00 01 02 03 04 05 06 07 08 09 0A 0B 0C 
55 


AA 02 
		0A 05 
			0A 04 
				0A 03 
					0A 02 
						0A 01 
							0A 00 
							00 0B 
						00 0B 
					01 0B 
				02 0B 
			03 0B 
		04 0B 
55 

AA 03 AB 55 
AA 04 CD 55 
AA 05 EF 55 
AA 06 1A 55 
AA 07 1B 55

AA 08 
	07 06 05 04 03 02 01 00 
	00 01 02 03 04 05 06 07 
	E7 C7 E6 C6 E5 C5 E4 C4 E3 C3 E2 C2 E1 C1 E0 C0 
	E0 C0 E1 C1 E2 C2 E3 C3 E4 C4 E5 C5 E6 C6 E7 C7 
55

AA 09 
	11 07 
	10 06 
	0F 05 
	0E 04 
	0D 03 
	0C 02 
	0B 01 
	0A 00 
	
	2D 17 2D 07 
	2D 16 2D 06 
	2D 15 2D 05 
	2D 14 2D 04 
	2D 13 2D 03 
	2D 12 2D 02 
	2D 11 2D 01 
	2D 10 2D 00 
55

******************************************/
